package ds.students;

import ds.students.Token.Type;

/**
 * @author simont
 */
public class Calculator {

    public DSQueue infixToPostfix(DSQueue infix) {
        DSStack operater = new DSStack();
        DSQueue output = new DSQueue();
        while (!infix.isEmpty()) {
            Token peek = infix.poll();
            if (peek.type == Type.OPERAND) {
                output.offer(peek);
            } else if (peek.type == Type.OPERATOR) {
                if (operater.isEmpty() || "(".equals(operater.peek().getOperator()) || peek.getPrecedence() > operater.peek().getPrecedence()) {
                    operater.push(peek);
                } else {
                    //否则将栈中元素出栈如队，直到遇到大于当前操作符或者遇到左括号时
                    while (!operater.isEmpty() && !"(".equals(operater.peek().getOperator())) {
                        if (peek.getPrecedence() <= operater.peek().getPrecedence()) {
                            output.offer(operater.pop());
                        }else
                        	break;
                    }
                    //当前操作符压栈
                    operater.push(peek);
                }
            }else if("(".equals(peek.getOperator())){
				//是左括号，压栈
				operater.push(peek);
			}else if(")".equals(peek.getOperator())){
				//是右括号 ，将栈中元素弹出入队，直到遇到左括号，左括号出栈，但不入队
				while (!operater.isEmpty()){
					if("(".equals(operater.peek().getOperator())){
						operater.pop();
						break;
					}else {
						output.offer(operater.pop());
					}
				}
			}
        }
		//循环完毕，如果操作符栈中元素不为空，将栈中元素出栈入队
		while (!operater.isEmpty()){
			output.offer(operater.pop());
		}
		return output;
    }


    public double evaluatePostfix(DSQueue exp) {
		DSStack stack = new DSStack();
		while(!exp.isEmpty()){
			Token poll = exp.poll();
			if(poll.type == Type.OPERAND){
				//是数字
				stack.push(poll);
			}else {
				//是操作符，取出栈顶两个元素
				double num2 = stack.pop().getOperand();
				double num1 = stack.pop().getOperand();
				double res = 0;
				String item = poll.getOperator();
				if(item.equals("+")){
					res = num1 + num2;
				}else if(item.equals("-")){
					res = num1 - num2;
				}else if(item.equals("*")){
					res = num1 * num2;
				}else if(item.equals("/")){
					res = num1 / num2;
				}else {
					throw new RuntimeException("运算符错误！");
				}
				stack.push(new Token(res));
			}
		}
		return stack.pop().getOperand();
    }
}
